<?php
namespace app\api\controller;

/*
    2024年09月23日 备注

    Insurance表是保单表

    choose字段 用于出单表选择保单

    status字段 用于确认保单生命周期的状态
    0  为报价单
    10 为待付款
    20 待上传pdf（财务已付款，或者不需要现结的，就到待上传状态）
    30 为已完成（已上传pdf）


    待付款列表（状态为10）
    待结算列表（已完成状态，pay_time又为0，表示还未付款）

    是否有效看到期时间

    有效保单（上传啊pdf才有效）

*/

class Insurance extends Permission
{
    private function _getList($map)
    {
        $page = isset($this->input_data['page']) ? $this->input_data['page'] : 1;
        $limit = isset($this->input_data['limit']) ? $this->input_data['limit'] : 15;
        
        $total = db('Insurance')->alias('a')->join('vehicle b','a.vehicle_id = b.id','LEFT')->where($map)->count();
        $rows = db('Insurance')->alias('a')->join('vehicle b','a.vehicle_id = b.id','LEFT')->field('a.*,b.plate_number,b.company,b.area')->order('id', 'desc')->page($page,$limit)->where($map)->select();
        $sql = db()->getLastSql();

        $list = [];
        $chooseIds = [];
        foreach ($rows as $v) {
            
            # 总价，强险的加车船税进去，中润的加加价进去
            $v['totalPrice'] = formatMoneyShow( bcadd( bcadd($v['price'],$v['tax_price']), $v['raise_price']) );
            # 加价或者车船税
            $otherPrice = $v['cate'] == '交强险' ? $v['tax_price'] : $v['raise_price'];
            $v['otherPrice'] = formatMoneyShow($otherPrice);

            # 处理实际支付,2025年02月20日不懂是什么鸟了
            $v = $this->_getPriceActual($v);

            $v['price'] = formatMoneyShow($v['price']);
            $v['raise_price'] = formatMoneyShow($v['raise_price']);
            $v['tax_price'] = formatMoneyShow($v['tax_price']);
            $v['rebate_amount'] = formatMoneyShow($v['rebate_amount']);
            $v['rebate_amount_paid'] = formatMoneyShow($v['rebate_amount_paid']);

            $v['pay_time'] = $v['pay_time'] > 0 ? date('Y-m-d H:i:s',$v['pay_time']) : '';
            $v['rebate_pay_time'] = $v['rebate_pay_time'] > 0 ? date('Y-m-d H:i:s',$v['rebate_pay_time']) : '';
            $v['rebateTime'] = $v['rebate_time'] > 0 ? date('Y-m-d H:i:s',$v['rebate_time']) : '';
            $v['createDate'] = $v['create_time'] > 0 ? date('Y-m-d H:i',$v['create_time']) : '';
            $v['rebate'] = $v['rebate'] * 1;
            $v['payImages'] = json_decode($v['pay_images'],true);
            $v['rebateImages'] = json_decode($v['rebate_images'],true);
            $v['offerImages'] = json_decode($v['images'],true);


            


            # 处理申请者
            $v = $this->_formatApply($v);

            # 起始时间
            $v = $this->_formatDeadline($v);

            # 保单状态
            $v = $this->_getInsuranceStatus($v);

            if($v['choose'] == 1) $chooseIds[] = $v['id'];

            $list[] = $v;
        }
        
        $data = [
            'total' => $total,
            'list' => $list,
            'chooseIds' => $chooseIds,
            'sql' => $sql,
            'map' => $map
        ];
        return $data;
    }

    // 实付金额，普通保险等于price 中润的等于净费
    private function _getPriceActual($v)
    {
        $v['amountView'] = formatMoneyShow($v['price'] + $v['raise_price']);
        if($v['insurance_id'] == 1)
        {
            $v['priceActual'] = formatMoneyShow($v['price'] - $v['rebate_amount']);
        }
        else
        {
            $v['priceActual'] = formatMoneyShow($v['price']);
            
        }

        return $v;
    }

    private function _formatApply($v)
    {
        if($v['apply_user_id'] == 0)
        {
            $v['apply_user'] = '主动报价';
            $v['applyTime'] = '/';
        }
        else
        {
            $v['applyTime'] = date('Y-m-d H:i',$v['apply_time']);
        }
        return $v;
    }

    // 保险列表（已生效的）
    public function getList()
    {
        $map = [
            'a.status' => 30
        ];
        if( $this->post('plate_number') != '' ) $map['b.plate_number'] = ['LIKE','%'.$this->input_data['plate_number'].'%'];
        if( $this->post('company') != '' ) $map['b.company'] = ['LIKE','%'.$this->input_data['company'].'%'];
        if( $this->post('vehicle_id') > 0 ) $map['vehicle_id'] = $this->input_data['vehicle_id'];
        if( $this->post('cate') != '' ) $map['cate'] = $this->input_data['cate'];
        if($this->post('area_id') > 0)
        {
            $map['area_id'] = $this->post('area_id');
        }
        else
        {
            $map['area_id'] = ['IN',$this->myAllAreaIds];
        }

        $data = $this->_getList($map);
        
        $this->resSuc($data);
    }
    // 报价单列表
    public function getOfferList()
    {
        $map = [
        ];
        if( $this->post('plate_number') != '' ) $map['b.plate_number'] = ['LIKE','%'.$this->input_data['plate_number'].'%'];

        if( $this->post('company') != '' ) $map['b.company'] = ['LIKE','%'.$this->input_data['company'].'%'];

        if( isset($this->input_data['cate']) && $this->input_data['cate'] != '' ) $map['a.cate'] = $this->input_data['cate'];
        if( isset($this->input_data['plan_id']) && $this->input_data['plan_id'] != '' ) $map['a.plan_id'] = $this->input_data['plan_id'];
        if( isset($this->input_data['vehicle_id']) && $this->input_data['vehicle_id'] > 0 ) $map['a.vehicle_id'] = $this->input_data['vehicle_id'];

        if( $this->post('choose') != '' ) $map['a.choose'] = $this->post('choose');

        if($this->post('area_id') > 0)
        {
            $map['area_id'] = $this->post('area_id');
        }
        else
        {
            $map['area_id'] = ['IN',$this->myAllAreaIds];
        }

        $data = $this->_getList($map);
        $this->resSuc($data);
    }

    // 出单表获取报价单列表、保险列表
    public function getTradeOfferList()
    {
        $map = [
            'vehicle_id' => $this->post('vehicle_id')
        ];

        if( $this->post('choose') != '' ) $map['a.choose'] = $this->post('choose');
        if( $this->post('trade_id') != '' ) $map['a.trade_id'] = $this->post('trade_id');
        if( $this->post('status') != '' ) $map['a.status'] = $this->post('status');


        $data = $this->_getList($map);
        $this->resSuc($data);
    }

    // 出单表获取报价单列表、保险列表
    public function getWatingBuyInsurance()
    {
        $map = [
            'vehicle_id' => $this->post('vehicle_id')
        ];

        if( $this->post('choose') != '' ) $map['a.choose'] = $this->post('choose');
        if( $this->post('trade_id') != '' ) $map['a.trade_id'] = $this->post('trade_id');
        if( $this->post('status') != '' ) $map['a.status'] = $this->post('status');


        $data = $this->_getList($map);
        $this->resSuc($data);
    }

    // 待付款的保单
    public function getWatingPayList()
    {
        
        $map = [
            'a.status' => 10
        ];

        if( isset($this->input_data['plate_number']) ) $map['b.plate_number'] = ['LIKE','%'.$this->input_data['plate_number'].'%'];
        if( isset($this->input_data['company']) ) $map['b.company'] = ['LIKE','%'.$this->input_data['company'].'%'];

        if( isset($this->input_data['area_id']) && $this->input_data['area_id'] > 0 ) $map['area_id'] = $this->input_data['area_id'];

        if( $this->post('vehicle_id') > 0 ) $map['vehicle_id'] = $this->input_data['vehicle_id'];


        
        
        $data = $this->_getList($map);
        $this->resSuc($data);
    }
    // 待上传pdf的保单
    public function getWatingCompleteList()
    {
        $map = [
            'a.status' => 20
        ];

        if( isset($this->input_data['plate_number']) ) $map['b.plate_number'] = ['LIKE','%'.$this->input_data['plate_number'].'%'];
        if( isset($this->input_data['company']) ) $map['b.company'] = ['LIKE','%'.$this->input_data['company'].'%'];

        if( isset($this->input_data['area_id']) && $this->input_data['area_id'] > 0 ) $map['area_id'] = $this->input_data['area_id'];

        $data = $this->_getList($map);
        $this->resSuc($data);
    }
    // 待上传退统pdf
    public function getWatingRefundCompleteList()
    {
        $map = [
            'a.status' => 30,
            'refund_time' => ['>',0],
            'refund_pdf' => ['EQ','']
        ];

        if( isset($this->input_data['plate_number']) ) $map['b.plate_number'] = ['LIKE','%'.$this->input_data['plate_number'].'%'];
        if( isset($this->input_data['company']) ) $map['b.company'] = ['LIKE','%'.$this->input_data['company'].'%'];

        if( isset($this->input_data['area_id']) && $this->input_data['area_id'] > 0 ) $map['area_id'] = $this->input_data['area_id'];

        $data = $this->_getList($map);
        $this->resSuc($data);
    }

    private function _formatDeadline($v){
        $s = $v['s_time'];
        $e = $v['e_time'];

        $v['sTime'] = $s == 0 ? '' : date('Y年m月d日 H时',$s);
        $v['eTime'] = $e == 0 ? '' : date('Y年m月d日 H时',$e);
        $v['s_time_date'] = $s == 0 ? '' : date('Y-m-d',$s);
        $v['s_time_h'] = $s == 0 ? '' : date('h',$s);
        $v['s_time_i'] = $s == 0 ? '' : date('i',$s);
        $v['e_time_date'] = $e == 0 ? '' : date('Y-m-d',$e);
        $v['e_time_h'] = $e == 0 ? '' : date('h',$e);
        $v['e_time_i'] = $e == 0 ? '' : date('i',$e);
        $v['time'] = $v['sTime'].' - '.$v['eTime'];

        return $v;
    }
    // 获取保单的状态
    public function _getInsuranceStatus($v)
    {
        $v['canRefund'] = 0;
        //* 已退保，生效中，未生效 */
        if($v['status'] == 30)
        {
            if($v['refund_time'] > 0 && strtotime($v['refund_date']) < time())
            {
                $statusText = '已退保';
                $statusTag = 'danger';
            }
            else
            {
                if($v['e_time'] > time())
                {
                    $statusText = '生效中';
                    $statusTag = 'success';
                    // 生效中的保单30 并且refund_time为0的 才能退保
                    // 因为目前退保流程，选择的实际退保日期有可能是未来时间。没到时间之前保单状态就是生效中，这种情况就不显示退保了
                    if($v['refund_time'] == 0) $v['canRefund'] = 1;
                }
                else
                {
                    $statusText = '已过期';
                    $statusTag = 'info';
                }
            }
        }
        else
        {
            if($v['status'] == 20)
            {
                $statusText = '待上传保单';
                $statusTag = 'primary';
            }
            if($v['status'] == 10)
            {
                $statusText = '待付款';
                $statusTag = 'warning';
            }
            if($v['status'] == 0)
            {
                $statusText = '报价单';
                $statusTag = '';
            }
        }
        $v['statusText'] = $statusText;
        $v['statusTag'] = $statusTag;
        return $v;
    }
    // 初始化报价列表
    private function _initOfferList()
    {
        $list = [];
        // 如果是出单选择的列表，则把其他险种加上去
        if( isset($this->input_data['action']) && $this->input_data['action'] == 'choose' )
        {
            $otherItems = ['超赔','安全责任','司机意外'];
            foreach ($otherItems as $k => $v) {
                $row = [
                    'id' => ($k+1) * - 1,
                    'cate' => $v
                ];
                $list[] = $row;
            }
            
        }
        
        return $list;
    }
    // 报价或者买保险？
    public function update()
    {
        $deadline = $this->_getDeadline();
        $salesman = $this->_getSalesman();
        $apply = $this->_getApply(); // 申请人
        // price是10000元 rebate是百分比40 这里计算出来的价格单位是分
        $vehicle = db('Vehicle')->where(['id'=>$this->post('vehicle_id')])->find();
        $rebateAmount = $this->_getReabteAmount();
        $data = [
            'insurance_salesman' => $salesman['realname'],
            'insurance_salesman_id' => $salesman['id'],
            'vehicle_id' => $this->input_data['vehicle_id'],
            'cate' => $this->input_data['cate'],
            'price' => formatMoneySave($this->input_data['price']),
            'tax_price' => formatMoneySave($this->input_data['tax_price']),
            'raise_price' => formatMoneySave($this->input_data['raise_price']),
            'rebate' => $this->input_data['rebate'],
            'rebate_amount' => $rebateAmount,
            'insurance' => $this->input_data['insurance'],
            'insurance_id' => $this->input_data['insurance_id'],
            'plan_id' => $this->input_data['plan_id'],
            'trade_id' => $this->input_data['trade_id'],
            'create_time' => time(),
            'create_user' => $this->user['realname'],
            'create_user_id' => $this->user['id'],
            'apply_time' => $apply['apply_time'],
            'apply_user' => $apply['apply_user'],
            'apply_user_id' => $apply['apply_user_id'],
            'images' => $this->input_data['images'],
            's_time' => $deadline['s_time'],
            'e_time' => $deadline['e_time']
        ];

        $offerId = $this->input_data['id'];

        if($this->input_data['id'] > 0)
        {
            # 如果要修改的报价单相关的出单表不是待完善状态，就不能修改了，否则会影响出单表其他数据。
            if($this->post('trade_id') > 0)
            {
                $trade = db('Trade')->where(['id'=>$this->post('trade_id')])->find();
                if( $trade['status'] > 5 ) $this->resErr('此报价单相关的出单表已进入后续流程，无法修改');
            }
            
            db('Insurance')->where(['id'=>$offerId])->update($data);

            # 报价单更新后，更新相关的出单表的信息
            $this->_updateTradePrice($this->post('id'));

            $nData = [
                'role' => 27,
                'title' => $this->user['realname'].'更新了'.$vehicle['plate_number'].'的报价单'
            ];
            db('NoticeList')->insert($nData);
        }
        else
        {
            $nData = [
                'role' => 27,
                'title' => $this->user['realname'].'新增了'.$vehicle['plate_number'].'的报价单'
            ];
            db('NoticeList')->insert($nData);
            $offerId = db('Insurance')->insertGetId($data);
        }



        # 更新报价次数
        $this->_updateOfferTimes($this->input_data['plan_id']);

        # 更新车辆的报价单数量
        $this->_updateVehicleInsuranceOfferTimes($this->input_data['vehicle_id']);
        # 商业险的话，保存详细
        // if($this->input_data['cate'] == '商业险') $this->_updateOfferDetail($offerId);
        # 更新险种列表
        $this->_updateInsuranceCate();
        $this->resSuc('ok');
    }

    private function _updateTradePrice($insuranceId)
    {
        $insurance = db('Insurance')->where(['id'=>$insuranceId])->find();
        # 如果此报价单已被出单表选中，出单表的价格也要跟着更新
        if($insurance['trade_id'] > 0){

            # 相关出单表选中的所有报价单
            $iMap = [
                'trade_id' => $insurance['trade_id'],
                'choose' => 1
            ];
            $insurances = db('Insurance')->where($iMap)->select();

            $qxPrice = $syxPrice = $qtxPrice = $tax = 0;
            // 更新选中数据

            foreach ($insurances as $v) {
                if($v['cate'] == '交强险')
                {
                    $tax = $v['tax_price'];
                    $qxPrice = $v['price'];
                }
                else if($v['cate'] == '商业险')
                {
                    $syxPrice = $v['price'];
                }
                else
                {
                    $qtxPrice += $v['price'];
                }
            }
            
            # 更新出单表的保险价格
            $trade = [
                'id' => $insurance['trade_id'],
                'tax_price' => $tax,
                'syx_price' => $syxPrice,
                'qx_price' => $qxPrice,
                'qtx_price' => $qtxPrice,
            ];
            db('Trade')->update($trade);

            # 更新出单表应付总价
            $uData = [
                'tradeId' => $insurance['trade_id']
            ];
            action('common/Trade/updatePrice',$uData);
        }
    }


    private function _updateInsuranceCate()
    {
        $map = [
            'title' => $this->input_data['cate']
        ];
        if(!db('InsuranceCate')->where($map)->find())
        {
            $data = [
                'title' => $this->input_data['cate'],
                'other' => 1
            ];
            db('InsuranceCate')->insert($data);
        }
    }
    // 计算返点
    private function _getReabteAmount()
    {
    
        $rebateAmount = bcmul($this->input_data['price'], $this->input_data['rebate'],2);

        return $rebateAmount;
    }
    // 获取报价申请人
    private function _getApply()
    {
        $data = [
            'apply_user' => '',
            'apply_user_id' => 0,
            'apply_time' => 0
        ];
        if($this->input_data['plan_id'] == 0) return $data;

        $map = [
            'id' => $this->input_data['plan_id']
        ];
        $plan = db('InsurancePlan')->where($map)->find();
        $data = [
            'apply_user' => $plan['create_user'],
            'apply_user_id' => $plan['create_user_id'],
            'apply_time' => $plan['create_time']
        ];
        return $data;

    }
    // 更新报价申请单里面的报价次数
    private function _updateOfferTimes($planId)
    {
        if($planId == 0) return false;
        $map = [
            'plan_id' => $planId
        ];
        $rows = db('Insurance')->where($map)->select();
        $cp = $hy = $jy = $az = $cy = $c = $b = $total  = 0;
        foreach ($rows as $v) {
            $total++;
            switch ($v['cate']) {
                case '交强险':
                    $c++;
                    break;
                case '商业险':
                    $b++;
                    break;
                case '超赔险':
                    $cp++;
                    break;
                case '货运险':
                    $hy++;
                    break;
                case '驾意险':
                    $jy++;
                    break;
                case '安责险':
                    $az++;
                    break;
                case '承运险':
                    $cy++;
                    break;
                
                default:
                    // code...
                    break;
            }
        }

        $pMap = [
            'id' => $planId
        ];
        $data = [
            'offer_times' => $total,
            'offer_c_times' => $c,
            'offer_b_times' => $b,
            'cp_times' => $cp,
            'cy_times' => $cy,
            'az_times' => $az,
            'hy_times' => $hy,
            'jy_times' => $jy,
        ];
        db('InsurancePlan')->where($pMap)->update($data);
    }
    // 更新车辆的报价单数量
    private function _updateVehicleInsuranceOfferTimes($vehicleId)
    {
        $map = [
            'vehicle_id' => $vehicleId,
            'status' => 0
        ];
        $count = db('Insurance')->where($map)->count();
        

        $pMap = [
            'id' => $vehicleId
        ];
        $data = [
            'insurance_offer' => $count,
        ];
        db('Vehicle')->where($pMap)->update($data);
    }

    // 商业险
    private function _updateOfferDetail($offerId)
    {
        db('InsuranceDetail')->where(['insurance_plan_offer_id'=>$offerId])->delete();
        $items = json_decode($this->input_data['items'],true);
        foreach ($items as $v) {
            $data = [
                'insurance_plan_offer_id' => $offerId,
                'title' => $v['title'],
                'max_pay' => formatMoneySave($v['max_pay']),
                'price' => formatMoneySave($v['price']),
            ];
            db('InsuranceDetail')->insert($data);
        }
    }
    private function _getSalesman()
    {
        # 逻辑
        # 业务员id为零 表示直接填写，新建并保存业务员
        $salesman = [
            'id' => $this->input_data['insurance_salesman_id'],
            'realname' => $this->input_data['insurance_salesman']
        ];

        if($this->input_data['insurance_salesman_id'] == 0)
        {
            $data = [
                'insurance_company_id' => $this->input_data['insurance_id'],
                'realname' => $this->input_data['insurance_salesman']
            ];
            # 先判断提交的业务员名字是否存在，不存在才添加
            if($sales = db('InsuranceCompanySalesman')->where($data)->find())
            {
                $salesman['id'] = $sales['id'];
            }
            else
            {
                $sId = db('InsuranceCompanySalesman')->insertGetId($data);
                $salesman['id'] = $sId;
            }
        }
        return $salesman;
    }

    private function _getDeadline()
    {
        $sh = $this->input_data['s_time_h'] ? $this->input_data['s_time_h'] : 0;
        $eh = $this->input_data['e_time_h'] ? $this->input_data['e_time_h'] : 0;
        $eh = 0;
        $si = $this->input_data['s_time_i'] ? $this->input_data['s_time_i'] : 0;
        $ei = $this->input_data['e_time_i'] ? $this->input_data['e_time_i'] : 0;
        $ei = 0;


        $s = $this->input_data['s_time_date'].' '.$sh.':'.$ei.':00';
        $e = $this->input_data['e_time_date'].' '.$eh.':'.$ei.':00';

        $data = [
            's_time' => strtotime($s),
            'e_time' => strtotime($e),
        ];
        return $data;
    }

    // 出单
    public function toBuy()
    {
        # 更改出单计划表状态
        $map = [
            'id' => $this->input_data['id']
        ];
        $data = [
            'status' => 20
        ];
        db('InsurancePlan')->where($map)->update($data);
        # 标记出单的报价记录
        $ids = json_decode($this->input_data['offerIds'],true);
        foreach ($ids as $v) {
            if($v['id'] > 0) // 商业险、强险
            {
                $offer = [
                    'id' => $v['id'],
                    'choose' => 1
                ];
                db('Insurance')->update($offer);
            }
            else // 其他固定价格的险种
            {
                $data = [
                    'choose' => 1,
                    'plan_id' => $this->input_data['id'],
                    'cate' => $v['cate']
                ];
                db('Insurance')->insert($data);
            }
            
        }
        $this->resSuc('ok');
    }

    # 上传保单的pdf
    # 有2种情况，1种是出单表出的保险，另一种是单独买的保险（退保出统或者退统出保）
    # 有传trade_id就表示是出单表的，就要更新出单表的状态
    public function updatePdf()
    {
        $map = [
            'id' => $this->input_data['id']
        ];
        $insurance = db('Insurance')->where($map)->find();
        $data = [
            'pdf' => $this->input_data['url'],
            'status' => 30
        ];
        db('Insurance')->where($map)->update($data);


        # 更新车辆保险到期时间
        if($this->post('action') == '第一次上传') $this->_updateVehicleInsuranceDate();

        # 更新出单表状态
        if(isset($this->input_data['trade_id']))
        {
            $data = [
                'tradeId' => $this->input_data['trade_id'],
                'action' => 'uploadPdf'
            ];
            action('common/Trade/updateStatus',$data);
        }

        # 创建车辆买保险的收支 $insurance['trade_id'] == 0 表示该保单不是通过出单表买的保险
        if($insurance['trade_id'] == 0 && $this->post('action') == '第一次上传')
        {
            $this->_createVehicleInsuranceCost($insurance);
        }
        

        $this->resSuc('ok');
    }

    
    // 创建车辆买保险的收支
    private function _createVehicleInsuranceCost($insurance)
    {
        $data['io_type'] = '支出';
        $data['images'] = '';
        $data['relation_type'] = '买保险';
        $data['relation_id'] = $insurance['id'];
        $data['status'] = 20; // 已完成

        $data['pay_user'] = $this->user['realname'];
        $data['pay_user_id'] = $this->user['id'];
        $data['pay_time'] = time();

        $data['create_user'] = $this->user['realname'];
        $data['create_user_id'] = $this->user['id'];
        $data['create_time'] = time();

        $data['pay_record_id'] = '';
        $data['vehicle_id'] = $insurance['vehicle_id'];
        $data['amount'] = $insurance['pay_amount'];
        $data['cate'] = '保险购买';
        db('VehicleIncomeExpense')->insertGetId($data);

        $data['io_type'] = '收入';
        $data['amount'] = $insurance['rebate_amount'];
        $data['cate'] = '保险返点';
        db('VehicleIncomeExpense')->insertGetId($data);

        # 更新车辆利润
        action('common/Vehicle/updateProfit',['vehicleId'=>$insurance['vehicle_id']]);

    }
    // 上传保单的pdf
    public function updateRefundPdf()
    {
        $map = [
            'id' => $this->input_data['id']
        ];

        $data = [
            'refund_pdf' => $this->input_data['url']
        ];
        db('Insurance')->where($map)->update($data);

        $this->resSuc('ok');
    }
    private function _updateVehicleInsuranceDate()
    {
        $map = [
            'id' => $this->input_data['vehicle_id']
        ];
        if($this->input_data['cate'] == '交强险')
        {
            $data = [
                'insurance_date_c' => date('Y-m-d',$this->input_data['e_time'])
            ];
            db('Vehicle')->where($map)->update($data);
        }
        if($this->input_data['cate'] == '商业险')
        {
            $data = [
                'insurance_date_b' => date('Y-m-d',$this->input_data['e_time'])
            ];
            db('Vehicle')->where($map)->update($data);
        }
    }
    public function updateQrcode()
    {
        $map = [
            'id' => $this->input_data['id']
        ];

        $data = [
            'pay_qrcode' => '["'.$this->input_data['url'].'"]'
        ];


        db('Insurance')->where($map)->update($data);

        $this->resSuc('ok');
    }

    // 废了
    public function getListByTradeId()
    {
        die;
        $page = isset($this->input_data['page']) ? $this->input_data['page'] : 1;
        $limit = isset($this->input_data['limit']) ? $this->input_data['limit'] : 15;
        $map = [
            'a.trade_id' => $this->input_data['trade_id'],
        ];
        if( isset($this->input_data['status']) ) $map['a.status'] = $this->input_data['status'];
        if( isset($this->input_data['cate']) && $this->input_data['cate'] != '' ) $map['a.cate'] = $this->input_data['cate'];
        if( isset($this->input_data['action']) && $this->input_data['action'] == '付款给保险公司' ) $map['a.cash'] = 1;

        $total = db('Insurance')->alias('a')->join('insurance_plan b','a.plan_id = b.id','LEFT')->where($map)->count();
        $rows = db('Insurance')->alias('a')->join('insurance_plan b','a.plan_id = b.id','LEFT')->field('a.*,b.remark_c,b.remark_b')->order('id', 'desc')->page($page,$limit)->where($map)->select();
        $list = [];
        foreach ($rows as $v) {
            $v['price'] = formatMoneyShow($v['price']);
            $v['rebate'] = $v['rebate'];
            $v['createDate'] = $v['create_time'] > 0 ? date('Y-m-d H:i',$v['create_time']) : '';
            # 起始时间
            $v = $this->_formatDeadline($v);
            # 付款图片数量
            $v['payImagesCount'] = $v['pay_images'] == '' ? 0 : count(explode(',', $v['pay_images']));
            $list[] = $v;
        }
        
        $data = [
            'total' => $total,
            'list' => $list
        ];
        $this->resSuc($data);
    }

    public function updatePayImages()
    {
        $data = [
            'id' => $this->input_data['id'],
            'pay_images' => $this->input_data['images'],
            'pay_user' => $this->user['realname'],
            'pay_user_id' => $this->user['id'],
            'pay_time' => time(),
        ];
        db('Insurance')->update($data);

        $this->resSuc('上传成功');
    }

    # 原来是中润的保单列表
    # 现在是待结账的保单列表 2024年06月14日
    public function getZrList()
    {
        $map = [
            'cash' => 0, // 不是现结
            'pay_time' => 0, // 没付款
            'a.status' => 30 // 已上传pdf，表示已经买好了保险
        ];
        if( isset($this->input_data['insurance_salesman']) ) $map['a.insurance_salesman'] = ['LIKE','%'.$this->input_data['insurance_salesman'].'%'];
        if( isset($this->input_data['insurance']) ) $map['a.insurance'] = ['LIKE','%'.$this->input_data['insurance'].'%'];
        
        
        $data = $this->_getList($map);
        $this->resSuc($data);
    }

    # 待收返点
    public function getRebateList()
    {   
        $map = [
            'pay_type' => '全款', // 全款结账的，才要收返点
            'a.status' => 30, // 30表示已上传完保单
            'rebate_status' => $this->post('rebate_status'),
            'pay_time' => ['>',0],
        ];
        if( isset($this->input_data['insurance_salesman']) ) $map['a.insurance_salesman'] = ['LIKE','%'.$this->input_data['insurance_salesman'].'%'];
        if( isset($this->input_data['insurance']) ) $map['a.insurance'] = ['LIKE','%'.$this->input_data['insurance'].'%'];
        
        $data = $this->_getList($map);

        $this->resSuc($data);
    }

    // 出单表选中保险报价后 更新数据
    public function updateTradeInsurance()
    {
        $tradeId = $this->input_data['trade_id'];

        # 更新报价表选中的数据
        // 先把所有选中的数据清空
        $iMap = [
            'vehicle_id' => $this->input_data['vehicle_id'], // 相关车辆
            'status' => 0, // 状态为报价单的
        ];
        db('Insurance')->where($iMap)->update(['choose'=>0,'trade_id'=>0]); // 选中状态和所属出单表都设为0

        $qxPrice = $syxPrice = $qtxPrice = $tax = 0;
        // 更新选中数据
        $list = json_decode($this->input_data['rows'],true);
        foreach ($list as $v) {
            $iMap = [
                'id' => $v['id']
            ];
            $iData = [
                'choose' => 1,
                'trade_id' => $this->input_data['trade_id']
            ];
            db('Insurance')->where($iMap)->update($iData);
            if($v['cate'] == '交强险')
            {
                $tax = formatMoneySave($v['tax_price']);
                $qxPrice = formatMoneySave($v['price']);
            }
            else if($v['cate'] == '商业险')
            {
                $syxPrice = formatMoneySave($v['price'] + $v['raise_price']);
            }
            else
            {
                $qtxPrice += formatMoneySave($v['price']);
            }
        }
        
        
        

        # 更新出单表的保险价格
        $data = [
            'tax_price' => $tax,
            'syx_price' => $syxPrice,
            'qx_price' => $qxPrice,
            'qtx_price' => $qtxPrice,
        ];
        db('Trade')->where(['id'=>$this->input_data['trade_id']])->update($data);

        // 更新出单表应付总价
        $data = [
            'tradeId' => $tradeId
        ];
        action('common/Trade/updatePrice',$data);
        // 更新出单表的利润
        $data = [
            'tradeId' => $tradeId
        ];
        action('common/Trade/updateProfit',$data);

        $this->resSuc('ok');
    }

    public function getPdfPath()
    {
        $map = [
            'trade_id' => $this->input_data['trade_id'],
            'choose' => 1,
            'cate' => $this->input_data['cate']
        ];
        if( !$data = db('Insurance')->where($map)->find() ) $this->resErr('无对应保险');

        if($data['pdf'] == '') $this->resErr('没有找到对应的保单');

        $this->resSuc($data['pdf']);

    }

    

    // 退保 已废除 
    public function refund()
    {
        # 标记已保
        $map = [
            'id' => $this->input_data['id']
        ];
        $insurance = db('Insurance')->where($map)->find();
        $data = [
            'refund_time' => time(),
            'refund_user' => $this->user['realname'],
            'refund_user_id' => $this->user['id'],
            'refund_amount' => formatMoneySave($this->input_data['refund_amount']),
            'refund_rebate' => formatMoneySave($this->input_data['refund_rebate']),
            'refund_pdf' => $this->input_data['refund_pdf'],
            'refund_date' => $this->input_data['refund_date'],
            'refund_type' => $this->input_data['refund_type'],
        ];
        db('Insurance')->where($map)->update($data);

        # 如果填写了实际退保日期，就标记对应的保险到期日期为实际退保日期
        $map = [
            'id' => $insurance['vehicle_id']
        ];
        if($this->input_data['refund_date'] != '')
        {
            $data = $insurance['cate'] == '交强险' ? ['insurance_date_c' => date('Y-m-d')] : ['insurance_date_b' => $this->input_data['refund_date']];
            db('Vehicle')->where($map)->update($data);
        }
        

        # 待收保险退款


        $this->resSuc('ok');
    }


    // 待退还保费列表
    public function getRefundList()
    {
        $page = isset($this->input_data['page']) ? $this->input_data['page'] : 1;
        $limit = isset($this->input_data['limit']) ? $this->input_data['limit'] : 15;
        $map = [
            'choose' => 1,
            'refund_amount' => ['>',0]
        ];
        // 待退款列表
        if ($this->input_data['cate'] == 'amount') $map['refund_amount_time'] = 0;
        // 待付返点列表
        if ($this->input_data['cate'] == 'rebate') $map['refund_rebate_time'] = 0;

        

        $total = db('Insurance')->where($map)->count();
        $rows = db('Insurance')->alias('a')->join('vehicle b','a.vehicle_id = b.id','LEFT')->field('a.*,b.plate_number')->page($page,$limit)->order('refund_time ASC')->where($map)->select();


        $list = [];
        foreach ($rows as $v) {
            $v['refund_amount'] = formatMoneyShow($v['refund_amount']);
            $v['refund_rebate'] = formatMoneyShow($v['refund_rebate']);

            $list[] = $v;
        }
        
        $data = [
            'total' => $total,
            'list' => $list
        ];
        $this->resSuc($data);
    }
    // 保险报表里面的
    public function getInsuranceReportList()
    {
        // =========================
        // # 计算提交上来的时间范围
        // =========================
        $ym        = trim($this->post('belongs_month'));
        if( $ym == '' )
        {
            $startDate = 0;
            $endDate = time();
        }
        else
        {
            $startDate = strtotime($ym . '-01 00:00:00');
            if ($startDate === false) $this->resErr('报表月份有误');
            $endDate   = strtotime('+1 month', $startDate);
        }

        $map = [
            'a.status' => 30,
            'company_id' => $this->post('company_id'),
            'trade_pay_time' => ['BETWEEN',[$startDate,$endDate]]
        ];

        switch ($this->post('cate')) {
            case '交强险':
                $map['a.cate'] = '交强险';
                break;
            case '商业险':
                $map['a.cate'] = '商业险';
                break;
            case '统筹':
                $map['a.cate'] = '商业险';
                $map['insurance_id'] = 1;
                break;
            case '正规':
                $map['a.cate'] = '正规';
                $map['insurance_id'] = ['NEQ',1];
                break;
            
            default:
                // code...
                break;
        }


        $data = $this->_getList($map);
        
        $this->resSuc($data);
    }

    // 已收退保费
    public function refundAmountDone()
    {
        # 创建付款记录
        $data = [
            'cate' => '退保',
            'type' => '收入',
            'relation_id' => $this->input_data['id'],
            'relation_name' => $this->input_data['plate_number'],
            'amount' => formatMoneySave($this->input_data['refund_amount_paid']),
            'images' => $this->input_data['refund_amount_images'],
            'create_user' => $this->user['realname'],
            'create_user_id' => $this->user['id'],
            'create_time' => time()
        ];

        $payRecordId = db('PayRecord')->insertGetId($data);

        # 更新保险状态
        $data = [
            'refund_amount_paid' => formatMoneySave($this->input_data['refund_amount_paid']),
            'refund_amount_pay_record_id' => $payRecordId,
            'refund_amount_images' => $this->input_data['refund_amount_images'],
            'refund_amount_time' => time(),
            'refund_amount_user' => $this->user['realname'],
            'refund_amount_user_id' => $this->user['id'],
        ];
        $id = $this->input_data['id'];
        db('Insurance')->where(['id'=>$id])->update($data);
        $this->resSuc('ok');
    }
    // 已退保费返点
    public function refundRebateDone()
    {
        # 创建付款记录
        $data = [
            'cate' => '退返点',
            'type' => '支出',
            'relation_id' => $this->input_data['id'],
            'relation_name' => $this->input_data['plate_number'],
            'amount' => formatMoneySave($this->input_data['refund_rebate']) * -1,
            'images' => $this->input_data['refund_rebate_images'],
            'create_user' => $this->user['realname'],
            'create_user_id' => $this->user['id'],
            'create_time' => time()
        ];

        $payRecordId = db('PayRecord')->insertGetId($data);

        $data = [
            'refund_rebate_pay_record_id' => $payRecordId,
            'refund_rebate_images' => $this->input_data['refund_rebate_images'],
            'refund_rebate_time' => time(),
            'refund_rebate_user' => $this->user['realname'],
            'refund_rebate_user_id' => $this->user['id'],
        ];
        $id = $this->input_data['id'];
        db('Insurance')->where(['id'=>$id])->update($data);
        $this->resSuc('ok');
    }   

    // 保险付款、复核
    public function pay()
    {
        $action = $this->post('action');
        $time = time();
        $payType = $this->post('type');
        $payTime = strtotime($this->post('pay_time'));
        $list = json_decode($this->input_data['list'],true);
        $names = [];
        $amount = formatMoneySave($this->post('amount'));

        $names = implode(',', $names);

        # 处理付款记录，付款的时候新建、复核的时候修改
        if($action == '复核')
        {
            $payRecordId = $this->post('id');
            $data = [
                'status' => 200,
                'amount' => $amount * -1,
                'images' => $this->input_data['images'],
                'pay_time' => $payTime,
                'judge_user' => $this->user['realname'],
                'judge_user_id' => $this->user['id'],
                'judge_time' => $time
            ];

            db('PayRecord')->where(['id'=>$payRecordId])->update($data);
        }
        else
        {
            $data = [
                'cate' => '保险结账',
                'type' => '支出',
                'relation_id' => 0,
                'relation_name' => $names,
                'amount' => $amount * -1,
                'images' => $this->input_data['images'],
                'pay_time' => $payTime,
                'create_user' => $this->user['realname'],
                'create_user_id' => $this->user['id'],
                'create_time' => $time
            ];

            $payRecordId = db('PayRecord')->insertGetId($data);
        }
        

        # 更新“报价单（保单）”实际的付款信息【可能有多付也可能会少付】
        foreach ($list as $v) {
            # 现结的默认是全款，挂账的可选全款或者底价
            $totalPrice = formatMoneySave($v['price']) + formatMoneySave($v['tax_price']);

            $topAmount = $payType == '全款' ? $totalPrice : $totalPrice - formatMoneySave($v['rebate_amount']);
            $amountPaid = $amount > $topAmount ? $topAmount : $amount;
            $oData = [
                'id' => $v['id']
            ];
            $oData['pay_amount'] = $amountPaid; // 记录这个保险实际付了多少钱出去
            $oData['pay_record_id'] = $payRecordId;
            $oData['pay_type'] = $payType;
            $oData['pay_images'] = $this->input_data['images'];

            if($action == '复核')
            {
                $oData['pay_judge_user'] = $this->user['realname'];
                $oData['pay_judge_user_id'] = $this->user['id'];
                $oData['pay_judge_time'] = time();
            }
            else
            {
                // 现付给保险公司，状态改为20，待上传pdf
                if($v['cash'] == 1) $oData['status'] = 20;

                $oData['pay_user'] = $this->user['realname'];
                $oData['pay_user_id'] = $this->user['id'];
                $oData['pay_time'] = time();
            }

            db('Insurance')->update($oData);

            $amount -= $amountPaid;
        }

        # 多收部分返点放到第一个保险里面
        if($amount > 0)
        {
            $insurance = db('Insurance')->where(['id'=>$list[0]['id']])->find();
            $insurance['pay_amount'] += $amount;
            db('Insurance')->update($insurance);
        }

        # 更新保险实际的付款支出
        if($action == '复核') $this->_updateInsurancePayCost($payRecordId);

        # 更新出单表状态
        if(isset($this->input_data['trade_id']))
        {
            $data = [
                'tradeId' => $this->input_data['trade_id'],
                'action' => 'pay'
            ];
            action('common/Trade/updateStatus',$data);
        }
        

        $this->resSuc('ok');
    } 

    // 收到保险公司返点
    public function rebatePay()
    {
        $payTime = strtotime($this->post('pay_time'));
        $list = json_decode($this->input_data['list'],true);
        $insurance = $list[0]['insurance'];
        $amount = formatMoneySave($this->input_data['rebate_amount_paid']); // 实收金额

        # 处理收款记录
        $data = [
            'cate' => '返点收入',
            'type' => '收入',
            'relation_id' => 0,
            'relation_name' => $insurance,
            'amount' => $amount,
            'pay_time' => $payTime,
            'images' => $this->input_data['images'],
            
        ];
        if($this->post('action') == '复核')
        {
            $payRecordId = $this->post('id');
            $data['status'] = 200;
            $data['judge_user'] = $this->user['realname'];
            $data['judge_user_id'] = $this->user['id'];
            $data['judge_time'] = time();
            db('PayRecord')->where(['id'=>$payRecordId])->update($data);

            # 更新保险实际的返点收入
            $this->_updateInsuranceRebateCost($payRecordId);
        }
        else
        {
            $data['create_user'] = $this->user['realname'];
            $data['create_user_id'] = $this->user['id'];
            $data['create_time'] = time();
            $payRecordId = db('PayRecord')->insertGetId($data);
        }

        

        foreach ($list as $k => $v) {
            $rebateAmountPaid = $amount > formatMoneySave($v['rebate_amount']) ? formatMoneySave($v['rebate_amount']) : $amount;
            # 更新保险单收到的返点状态
            $data = [
                'rebate_status' => 200,
                'rebate_amount_paid' => $rebateAmountPaid,
                'rebate_pay_record_id' => $payRecordId,
                'rebate_pay_time' => $payTime,
                'rebate_images' => $this->input_data['images'],
            ];
            if($this->post('action') == '复核')
            {
                $data['rebate_judge_user'] = $this->user['realname'];
                $data['rebate_judge_user_id'] = $this->user['id'];
                $data['rebate_judge_time'] = time();
            }
            else
            {
                $data['rebate_user'] = $this->user['realname'];
                $data['rebate_user_id'] = $this->user['id'];
                $data['rebate_time'] = time();
            }
            $map = [
                'id' => $v['id']
            ];
            db('Insurance')->where($map)->update($data);
            $amount -= $rebateAmountPaid;
        }

        # 多收部分返点放到第一个保险里面
        if($amount > 0)
        {
            $insurance = db('Insurance')->where(['id'=>$list[0]['id']])->find();
            $insurance['rebate_amount_paid'] += $amount;
            db('Insurance')->update($insurance);
        }
        

        $this->resSuc('ok');
    }

    private function _updateInsuranceRebateCost($payRecordId)
    {
        # 找复核的支付记录有关的保险
        $payRecord = db('PayRecord')->where(['id'=>$payRecordId])->find();
        $map = [
            'rebate_pay_record_id' => $payRecordId
        ];
        $insurance = db('Insurance')->where($map)->select();
        $time = time();

        foreach ($insurance as $v) {

            $diff = $v['rebate_amount_paid'] - $v['rebate_amount'];

            # 如果实收返点和应收返点不一致
            if($diff != 0)
            {
                $data = [
                    'relation_type' => '返点收入',
                    'relation_id' => $payRecordId,
                    'images' => $payRecord['images'],
                    'status' => 20,
                    'pay_record_id' => $payRecordId,
                    'vehicle_id' => $v['vehicle_id'],
                    'pay_user' => $this->user['realname'],
                    'pay_user_id' => $this->user['id'],
                    'pay_time' => $time,
                    'create_user' => $this->user['realname'],
                    'create_user_id' => $this->user['id'],
                    'create_time' => $time
                ];
                
                if($diff > 0)
                {
                    $data['io_type'] = '收入';
                    $data['amount'] = $diff;
                    $data['cate'] = '多收返点';
                }
                if($diff < 0)
                {
                    $data['io_type'] = '支出';
                    $data['amount'] = $diff * -1;
                    $data['cate'] = '少收返点';
                }
                db('VehicleIncomeExpense')->insertGetId($data);
            }
        }
    }
    private function _updateInsurancePayCost($payRecordId)
    {
        # 找复核的支付记录有关的保险
        $payRecord = db('PayRecord')->where(['id'=>$payRecordId])->find();
        $map = [
            'pay_record_id' => $payRecordId
        ];
        $insurance = db('Insurance')->where($map)->select();
        $time = time();

        foreach ($insurance as $v) {

            # 算出应付多少
            $totalPrice = $v['price'] + $v['tax_price'];

            $totalPrice = $v['pay_type'] == '全款' ? $totalPrice : $totalPrice - $v['rebate_amount'];

            $diff = $totalPrice - $v['pay_amount'];

            # 如果实收返点和应收返点不一致
            if($diff != 0)
            {
                $data = [
                    'relation_type' => '保险结账',
                    'relation_id' => $payRecordId,
                    'images' => $payRecord['images'],
                    'status' => 20,
                    'pay_record_id' => $payRecordId,
                    'vehicle_id' => $v['vehicle_id'],
                    'pay_user' => $this->user['realname'],
                    'pay_user_id' => $this->user['id'],
                    'pay_time' => $time,
                    'create_user' => $this->user['realname'],
                    'create_user_id' => $this->user['id'],
                    'create_time' => $time
                ];
                
                if($diff > 0)
                {
                    $data['io_type'] = '收入';
                    $data['amount'] = $diff;
                    $data['cate'] = '保险结账少付';
                }
                if($diff < 0)
                {
                    $data['io_type'] = '支出';
                    $data['amount'] = $diff * -1;
                    $data['cate'] = '保险结账多付';
                }
                db('VehicleIncomeExpense')->insertGetId($data);
            }
        }
    }

    public function delete()
    {
        $map = [
            'id' => $this->input_data['id']
        ];
        $insurance = db('Insurance')->where($map)->find();

        if($insurance['choose'] == 1) $this->resErr('此报价单已被出单表选择，无法删除');
        db('Insurance')->where($map)->delete();

        $this->_updateVehicleInsuranceOfferTimes($this->input_data['vehicle_id']);
        $this->resSuc('ok');
    }
    
}



